package com.zxy.ziems.server.device.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zxy.ziems.server.alarm.pojo.entity.AlarmTypeEntity;
import com.zxy.ziems.server.alarm.service.AlarmTypeService;
import com.zxy.ziems.server.device.convertor.DeviceConvertor;
import com.zxy.ziems.server.device.mapper.DevicePropertyAlarmMapper;
import com.zxy.ziems.server.device.pojo.dto.DevicePropertyAlarmDTO;
import com.zxy.ziems.server.device.pojo.entity.DevicePropertyAlarmEntity;
import com.zxy.ziems.server.device.pojo.entity.DevicePropertyEntity;
import com.zxy.ziems.server.device.pojo.vo.DevicePropertyAlarmVO;
import com.zxy.ziems.server.device.service.DevicePropertyAlarmService;
import com.zxy.ziems.server.device.service.DevicePropertyService;
import com.zxy.ziems.server.device.service.DeviceService;
import com.zxy.ziems.server.mybatis.core.service.ServiceImplX;
import com.zxy.ziems.server.utils.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 10348359
 * @create 2024-03-28 10:00
 */
@Service
public class DevicePropertyAlarmServiceImpl extends ServiceImplX<DevicePropertyAlarmMapper, DevicePropertyAlarmEntity> implements DevicePropertyAlarmService {
    @Override
    public void add(DevicePropertyAlarmDTO dto) {
        AssertUtil.nonNull(deviceService.getById(dto.getDeviceId()), "设备不存在");
        AssertUtil.nonNull(alarmTypeService.getById(dto.getAlarmTypeId()), "告警类型不存在");
        DevicePropertyEntity propertyEntity = devicePropertyService.getById(dto.getDevicePropertyId());
        AssertUtil.nonNull(propertyEntity, "设备属性不存在");
        AssertUtil.isTrue(Objects.equals(dto.getDeviceId(), propertyEntity.getDeviceId()), "数据不匹配");

        DevicePropertyAlarmEntity entity = DeviceConvertor.INSTANCE.devicePropertyAlarmDTOConvert2DO(dto, propertyEntity.getDataTypeId());
        save(entity);
    }

    @Override
    public void update(DevicePropertyAlarmDTO dto) {
        DevicePropertyAlarmEntity entity = getById(dto.getId());
        AssertUtil.nonNull(entity, "配置不存在");
        AssertUtil.isTrue(Objects.equals(entity.getDeviceId(), dto.getDeviceId()), "设备不能变更");
        AssertUtil.nonNull(deviceService.getById(dto.getDeviceId()), "设备不存在");
        AssertUtil.nonNull(alarmTypeService.getById(dto.getAlarmTypeId()), "告警类型不存在");
        DevicePropertyEntity propertyEntity = devicePropertyService.getById(dto.getDevicePropertyId());
        AssertUtil.nonNull(propertyEntity, "设备属性不存在");
        AssertUtil.isTrue(Objects.equals(dto.getDeviceId(), propertyEntity.getDeviceId()), "数据不匹配");

        entity = DeviceConvertor.INSTANCE.devicePropertyAlarmDTOConvert2DO(dto, propertyEntity.getDataTypeId());
        updateById(entity);
    }

    @Override
    public void deleteById(String id) {
        removeById(id);
    }

    @Override
    public List<DevicePropertyAlarmVO> viewListByDeviceId(String deviceId) {
        if (StrUtil.isBlank(deviceId)) {
            return new ArrayList<>(0);
        }
        List<DevicePropertyAlarmEntity> list = list(DevicePropertyAlarmEntity::getDeviceId, deviceId);
        Set<String> deviceIdSet = new HashSet<String>();
        Set<String> alarmTypeIdSet = new HashSet<>();
        list.forEach((entity) -> {
            if (Objects.nonNull(entity.getDeviceId())) {
                deviceIdSet.add(entity.getDeviceId());
            }
            if (Objects.nonNull(entity.getAlarmTypeId())) {
                alarmTypeIdSet.add(entity.getAlarmTypeId());
            }
        });

        List<DevicePropertyEntity> propertyEntities = devicePropertyService.listByDeviceIds(deviceIdSet);
        Map<String, Map<String, DevicePropertyEntity>> propertyMap = propertyEntities.stream().collect(Collectors.groupingBy(DevicePropertyEntity::getDeviceId, Collectors.toMap(DevicePropertyEntity::getDataTypeId, (a) -> a)));

        List<AlarmTypeEntity> alarmTypeEntities = alarmTypeService.listByIds(alarmTypeIdSet);
        Map<String, AlarmTypeEntity> alarmTypeMap = alarmTypeEntities.stream().collect(Collectors.toMap(AlarmTypeEntity::getId, (a) -> a));

        DeviceConvertor instance = DeviceConvertor.INSTANCE;
        return list.stream()
                .map((entity) -> instance.devicePropertyAlarmDOConvert2VO(
                                entity,
                                propertyMap.getOrDefault(entity.getDeviceId(), new HashMap<>()).get(entity.getDeviceDataTypeId()),
                                alarmTypeMap.get(entity.getAlarmTypeId())
                        )
                )
                .toList();
    }

    @Override
    public List<DevicePropertyAlarmEntity> listByDeviceId(String deviceId, String dataTypeId) {
        LambdaQueryWrapper<DevicePropertyAlarmEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevicePropertyAlarmEntity::getDeviceId, deviceId)
                .eq(DevicePropertyAlarmEntity::getDeviceDataTypeId, dataTypeId);
        return baseMapper.selectList(wrapper);
    }

    /**
     * 删除通过设备id
     *
     * @param deviceId
     * @return
     */
    @Override
    public int removeByDeviceId(String deviceId) {
        LambdaQueryWrapper<DevicePropertyAlarmEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevicePropertyAlarmEntity::getDeviceId, deviceId);
        return baseMapper.delete(wrapper);
    }

    private AlarmTypeService alarmTypeService;

    @Autowired
    public void setAlarmTypeService(AlarmTypeService alarmTypeService) {
        this.alarmTypeService = alarmTypeService;
    }

    private DevicePropertyService devicePropertyService;

    @Autowired
    public void setDevicePropertyService(DevicePropertyService devicePropertyService) {
        this.devicePropertyService = devicePropertyService;
    }

    private DeviceService deviceService;

    @Autowired
    public void setDeviceService(DeviceService deviceService) {
        this.deviceService = deviceService;
    }
}
